/**
 * 
 */
package org.hackystat.projecttrajectory.resource.estimate;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.math.BigInteger;
import java.util.List;
import org.hackystat.project.ProjectException;
import org.hackystat.projecttrajectory.ProjectTrajectoryProperties;
import org.hackystat.projecttrajectory.client.ProjectTrajectoryClient;
import org.hackystat.projecttrajectory.client.ProjectTrajectoryException;
import org.hackystat.projecttrajectory.resource.estimate.jaxb.EstimateData;
import org.hackystat.projecttrajectory.resource.estimate.jaxb.EstimateIndex;
import org.hackystat.projecttrajectory.resource.estimate.jaxb.EstimateRef;
import org.hackystat.projecttrajectory.resource.estimate.jaxb.ProjectEstimate;
import org.hackystat.projecttrajectory.test.ProjectTrajectoryTestHelper;
import org.hackystat.sensorbase.client.SensorBaseClient;
import org.hackystat.sensorbase.client.SensorBaseClientException;
import org.hackystat.utilities.stacktrace.StackTrace;
import org.hackystat.utilities.tstamp.Tstamp;
import org.junit.Test;

/**
 * Tests the project estimate REST API.
 * 
 * @author Cam Moore
 * 
 */
public class TestProjectEstimateRestApi extends ProjectTrajectoryTestHelper {
  /** The user for this test case. */
  private String user = "TestEstimate@hackystat.org";
  /** Second test user */
  private String user2 = "TestEstimate2@hackystat.org"; 
  
  private static final String defaultProject = "Default";

  /**
   * Test the putting a new estimate for the Default project.
   */
  @Test
  public void testPutDefaultEstimate() {
    try {
      ProjectTrajectoryProperties properties = ProjectTrajectoryProperties.getInstance();
      properties.setTestProperties();
      // Connect to the sensorbase and register the users.
      SensorBaseClient.registerUser(getSensorBaseHostName(), user);
      ProjectTrajectoryClient client = new ProjectTrajectoryClient(getProjectTrajectoryHostName(),
          user, user);
      client.authenticate();
      ProjectEstimate estimate = new ProjectEstimate();
      estimate.setEstimator(user);
      estimate.setProject(defaultProject);
      estimate.setLastModDate(Tstamp.makeTimestamp("2007-10-31"));
      EstimateData data = new EstimateData();
      data.setTotalEffort(BigInteger.valueOf(1000));
      data.setActiveDays(BigInteger.valueOf(5));
      data.setTotalSize(BigInteger.valueOf(4025));
      data.setEstimateDate(Tstamp.makeTimestamp("2007-11-11"));
      estimate.getEstimateData().add(data);
      client.putProjectEstimate(estimate);
    } catch (ProjectException e) {
      fail("Could not instantiate ProjectTrajectoryProperties");
    } catch (ProjectTrajectoryException e) {
      e.printStackTrace();
      fail("Could not authenticate");
    } catch (SensorBaseClientException e) {
      e.printStackTrace();
      fail("Could not register " + user);
    } catch (Exception e) {
      e.printStackTrace();
      fail("Could not create time stamp.");
    }
  }

  /**
   * Test the putting a new estimate for the Default project.
   */
  @Test
  public void testPutSecondDefaultEstimate() {
    try {
      ProjectTrajectoryProperties properties = ProjectTrajectoryProperties.getInstance();
      properties.setTestProperties();
      // Connect to the sensorbase and register the users.
      SensorBaseClient.registerUser(getSensorBaseHostName(), user2);
      ProjectTrajectoryClient client = new ProjectTrajectoryClient(getProjectTrajectoryHostName(),
          user2, user2);
      client.authenticate();
      ProjectEstimate estimate = new ProjectEstimate();
      estimate.setEstimator(user2);
      estimate.setProject(defaultProject);
      estimate.setLastModDate(Tstamp.makeTimestamp("2007-11-02"));
      EstimateData data = new EstimateData();
      data.setTotalEffort(BigInteger.valueOf(2000));
      data.setActiveDays(BigInteger.valueOf(10));
      data.setTotalSize(BigInteger.valueOf(8050));
      data.setEstimateDate(Tstamp.makeTimestamp("2007-11-22"));
      estimate.getEstimateData().add(data);
      client.putProjectEstimate(estimate);
    } catch (ProjectException e) {
      fail("Could not instantiate ProjectTrajectoryProperties");
    } catch (ProjectTrajectoryException e) {
      e.printStackTrace();
      fail("Could not authenticate");
    } catch (SensorBaseClientException e) {
      e.printStackTrace();
      fail("Could not register " + user);
    } catch (Exception e) {
      e.printStackTrace();
      fail("Could not create time stamp.");
    }
  }

  /**
   * Test getting a user's EstimateIndex
   */
  @Test
  public void testGetUserEstimateIndex() {
    try {
      ProjectTrajectoryProperties properties = ProjectTrajectoryProperties.getInstance();
      properties.setTestProperties();
      // Connect to the sensorbase and register the ProjectSummary user.
      SensorBaseClient.registerUser(getSensorBaseHostName(), user);
      ProjectTrajectoryClient client = new ProjectTrajectoryClient(getProjectTrajectoryHostName(),
          user, user);
      client.authenticate();
      EstimateIndex eIndex = client.getEstimateIndex(user);
      assertNotNull("Got null index", eIndex);
      List<EstimateRef> dataList = eIndex.getEstimateRef();
      assertNotNull("Got null dataList", dataList);
      assertTrue("Wrong number of estimates.", dataList.size() >= 1);
      ProjectEstimate estimate = client.getProjectEstimate(dataList.get(0));
      assertNotNull("Got null estimate", estimate);
      assertEquals("Got wrong estimator", user, estimate.getEstimator());
      assertEquals("Got wrong project", defaultProject, estimate.getProject());
      eIndex = null;
      dataList = null;
      estimate = null;
      // see if we can get user2's estimate
      eIndex = client.getEstimateIndex(user2);
      assertNotNull("Got null index", eIndex);
      dataList = eIndex.getEstimateRef();
      assertNotNull("Got null dataList", dataList);
//      System.out.println("Got " + dataList.size() + " extimates");
      assertEquals("Wrong number of estimates.", 1, dataList.size());
      estimate = client.getProjectEstimate(dataList.get(0));
      assertNotNull("Got null estimate", estimate);
      assertEquals("Got wrong estimator", user2, estimate.getEstimator());
      assertEquals("Got wrong project", defaultProject, estimate.getProject());
    } catch (Exception e) {
      fail("Got an error: " + StackTrace.toString(e));
    }    
  }
  

  /**
   * Test the getting the estimate for the Default project.
   */
  @Test
  public void testGetDefaultEstimate() {
    try {
      ProjectTrajectoryProperties properties = ProjectTrajectoryProperties.getInstance();
      properties.setTestProperties();
      // Connect to the sensorbase and register the ProjectSummary user.
      SensorBaseClient.registerUser(getSensorBaseHostName(), user);
      ProjectTrajectoryClient client = new ProjectTrajectoryClient(getProjectTrajectoryHostName(),
          user, user);
      client.authenticate();
      ProjectEstimate estimate = client.getProjectEstimate(user, defaultProject);
      assertNotNull("Estimate was null", estimate);
      assertEquals("Got wrong estimator", user, estimate.getEstimator());
      assertEquals("Got wrong project", defaultProject, estimate.getProject());
      List<EstimateData> dataList = estimate.getEstimateData();
      assertNotNull("No estimates in ProjectEstimate", dataList);
      assertFalse("No estimates in list", dataList.isEmpty());
    } catch (Exception e) {
      fail("Error in testGetDefaultEstimate " + StackTrace.toString(e));
    }
  }
  
  
}
